﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MYQQX
{

    /* AI 思路
     * 0. 比较已经有的卡牌，是否可以和桌面的某张牌凑成组合
     *    0.1 有: 选择
     *    0.2 无: 是否和手牌的某张凑成组合
     *       0.2.1 有：选择
     *       0.2.2 无：跳到1
     * 1. 将当前的手牌，和桌面一起，看是否可以有可实现的组合
     *    - 1.1 有：从手牌组其一选择（A1）
     *    - 1.2 判断桌面相同花色的，是否有属于组合的
     *       - 1.2.1 有: 选择（B1）[结束]
     *       - 1.2.2 无: 跳回 1.1 选择另外一个(A2)
     *       - 1.2.3 无：若组合已经使用完毕,则跳到2
     * 2. 无可实现的组合
     *    - 2.1: 选择自己卡牌花色与桌面花色差别最大的花色
     *    - 2.2：随机选择两张卡
     */
    public class AI
    {
        public List<Card> HaveList;
        public List<Card> HandList;
        public List<Card> DeskList;
        public Card DeskChose;
        public Card HandChose;
        private Random rand = new Random(Guid.NewGuid().GetHashCode());
        public void Go()
        {
            if (HaveList.Count > 0)
            {
                Check_0();
            }
            else
            {
                Check_1();
            }
        }

        private void Check_0()
        {
            // 获取桌面可以和已有牌凑组合，且组合分数最大的
            var dMatch = 0;
            Card dCard = null;
            foreach (var cd in DeskList)
            {
                if (!HandList.Any(t => t.JiJie == cd.JiJie))
                    continue;

                var newList = HaveList.ToArray().ToList();
                newList.Add(cd);

                var m = GroupConfig.Instance.GetGroups(newList)
                    .Where(t=> t.groups.Contains(cd.Name))
                    .Select(t => t.Score).Sum();
                if (m > 0 && m > dMatch)
                {
                    dMatch = m;
                    dCard = cd;
                }
            }
            if (dMatch > 0)
            {
                // 优先选择桌面的牌
                DeskChose = dCard;
                // 手牌则随机选一张即可
                var hList = HandList.Where(t => t.JiJie == DeskChose.JiJie).ToList();
                HandChose = hList[rand.Next(hList.Count)];
                return;
            }


            // 获取手牌可以和已有牌凑组合，且分数最大的
            var hMatch = 0;
            Card hCard = null;
            foreach (var cd in HandList)
            {
                if (!DeskList.Any(t => t.JiJie == cd.JiJie))
                    continue;

                var newList = HaveList.ToArray().ToList();
                newList.Add(cd);

                var m = GroupConfig.Instance.GetGroups(newList)
                    .Where(t => t.groups.Contains(cd.Name))
                    .Select(t => t.Score).Sum();

                if (m > 0 && m > dMatch)
                {
                    hMatch = m;
                    hCard = cd;
                }
            }
            if (hMatch > 0)
            {
                HandChose = hCard;
                // 桌面牌再筛选出可以和手牌+已有配对的
                var dList = DeskList.Where(t => t.JiJie == HandChose.JiJie).ToList();
                int Match = 0;
                foreach (var d in dList)
                {
                    var newList = HaveList.ToArray().ToList();
                    newList.Add(d);
                    newList.AddRange(HandList.ToArray());

                    var m = GroupConfig.Instance.GetGroups(newList)
                        .Where(t => t.groups.Contains(d.Name))
                        .Select(t => t.Score).Sum();

                    if (m > 0 && m > Match)
                    {   // 选取可以配对的分数最多的
                        Match = m;
                        DeskChose = d;
                    }
                }
                if (Match == 0)
                {
                    // 无配对，随便选一张了
                    DeskChose = DeskList[rand.Next(DeskList.Count)];
                }
            }

            // 都没有组合，进行下一组判断逻辑
            Check_1();
            
        }

        private void Check_1()
        {
            // 获取桌面有可以和手牌配对的
            int dMatch = 0;
            Card dCard = null;

            foreach (var d in DeskList)
            {
                if (!HandList.Any(t => t.JiJie == d.JiJie))
                    continue;

                var newList = HandList.ToArray().ToList();
                newList.Add(d);

                var m = GroupConfig.Instance.GetGroups(newList)
                    .Where(t => t.groups.Contains(d.Name))
                    .Select(t => t.Score).Sum();
                if (m > 0 && m > dMatch)
                {
                    dMatch = m;
                    dCard = d;
                }
            }
            if (dMatch > 0)
            {
                // 优先选择桌面的牌
                DeskChose = dCard;
                // 手牌则随机选一张即可
                var hList = HandList.Where(t => t.JiJie == DeskChose.JiJie).ToList();
                HandChose = hList[rand.Next(hList.Count)];
                return;
            }


            int hMatch = 0;
            Card hCard = null;

            foreach (var d in HandList)
            {
                if (!DeskList.Any(t => t.JiJie == d.JiJie))
                    continue;

                var newList = DeskList.ToArray().ToList();
                newList.Add(d);

                var m = GroupConfig.Instance.GetGroups(newList)
                    .Where(t => t.groups.Contains(d.Name))
                    .Select(t => t.Score).Sum();
                if (m > 0 && m > hMatch)
                {
                    hMatch = m;
                    hCard = d;
                }
            }
            if (hMatch > 0)
            {
                HandChose = hCard;
                // 桌面牌再筛选出可以和手牌+已有配对的
                var dList = DeskList.Where(t => t.JiJie == HandChose.JiJie).ToList();
                int Match = 0;
                foreach (var d in dList)
                {
                    var newList = HaveList.ToArray().ToList();
                    newList.Add(d);
                    newList.AddRange(HandList.ToArray());

                    var m = GroupConfig.Instance.GetGroups(newList)
                        .Where(t => t.groups.Contains(d.Name))
                        .Select(t => t.Score).Sum();

                    if (m > 0 && m > Match)
                    {   // 选取可以配对的分数最多的
                        Match = m;
                        DeskChose = d;
                    }
                }
                if (Match == 0)
                {
                    // 无配对，随便选一张了
                    DeskChose = DeskList[rand.Next(DeskList.Count)];
                }
            }

            // 都没有组合，进行下一组判断逻辑
            Check_2();
        }

        private void Check_2()
        {
            List<CardSeason> sList = new List<CardSeason>()
            {
                CardSeason.Chun,
                CardSeason.Xia,
                CardSeason.Qiu,
                CardSeason.Dong,
            };

            var mc = -100;
            var ms = CardSeason.Null;
            // 获取手牌和桌面都有，并且手牌颜色比桌面颜色多的最多的那个季节
            foreach (var s in sList)
            {
                var hCount = HandList.Count(t => t.JiJie == s);
                var dCount = DeskList.Count(t => t.JiJie == s);
                if (hCount == 0 || dCount == 0)
                    continue;

                var m = hCount - dCount;
                if (m > mc)
                {
                    mc = m;
                    ms = s;
                }
            }
            if (ms != CardSeason.Null)
            {
                var dList = DeskList.Where(t => t.JiJie == ms).ToList();
                var hList = HandList.Where(t => t.JiJie == ms).ToList();

                DeskChose = dList[rand.Next(dList.Count)];
                HandChose = hList[rand.Next(hList.Count)];
            }

            // 这时表示没有可以配对的！则需要进行换牌
            Check_3();
        }

        private void Check_3()
        {
            // 换牌的逻辑
            // 掉可以和已有卡牌组合成对的

            var nHandList = HandList.ToArray().ToList();
            foreach (var d in HandList)
            {
                var newList = HaveList.ToArray().ToList();
                newList.Add(d);

                var have = GroupConfig.Instance.GetGroups(newList)
                    .Where(t => t.groups.Contains(d.Name))
                    .Select(t => t.Score)
                    .Any();
                if (have)
                {
                    nHandList.RemoveAll(t => t.Name == d.Name);
                }
            }
            if (nHandList.Count <= 0)
            {
                nHandList = HandList;
            }

            var jgps = nHandList.GroupBy(t => t.JiJie).OrderByDescending(t => t.Count()).First().AsEnumerable().ToList();

            HandChose = jgps[rand.Next(jgps.Count)];
        }
    }
}
